#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QFileDialog>
#include <QDir>
#include <QFileInfoList>
#include <QStringList>
#include <QMap>
#include <QVector>
#include <algorithm>
#include <QStandardPaths>
#include <QProcess>
#include <QDebug>
#include <QMessageBox>
#include <QJsonArray>
#include <QJsonDocument>
#include <QKeyEvent>
#include <QCoreApplication>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , addedFiles()
    , fileNameToAbsolutePath()
{
    ui->setupUi(this);
    ui->stackedWidget->setCurrentIndex(0);
    ui->progressBar->setValue(0);
    ui->progressBar->setTextVisible(false);
    ui->lineEdit_outputImageFolderName->setPlaceholderText(tr("默认文件夹是output_image"));

}

MainWindow::~MainWindow()
{
    delete ui;
}

// 自定义比较函数 - 比较前缀的大小
bool comparePrefixes(const QString& a, const QString& b) {
    // 提取前缀中的数字部分
    bool ok;
    int numA = a.right(a.length() - 1).toInt(&ok);
    if (!ok) return false; // 如果转换失败，返回 false
    int numB = b.right(b.length() - 1).toInt(&ok);
    if (!ok) return false; // 如果转换失败，返回 false

    // 比较数字部分
    return numA < numB;
}

void MainWindow::on_pushButton_readAndConvert_clicked()
{
    ui->stackedWidget->setCurrentIndex(0);
    qDebug() << "获取当前页面的索引: " << ui->stackedWidget->currentIndex();
    qDebug() << "获取当前页面: " << ui->stackedWidget->currentWidget();
}

void MainWindow::on_pushButton_reconstructImage_clicked()
{
    ui->stackedWidget->setCurrentIndex(1);
    qDebug() << "获取当前页面的索引: " << ui->stackedWidget->currentIndex();
    qDebug() << "获取当前页面: " << ui->stackedWidget->currentWidget();
}

void MainWindow::on_comboBox_currentIndexChanged(int index)
{
    QString currentText = ui->comboBox->currentText();
    qDebug() << "Current index:" << index << "Current text:" << currentText;

    if (index == 0)
    {
        // 设置按钮和输入框可见
        ui->pushButton_readconvert->setText("读取ptu文件并转换为txt文件");
        ui->lineEdit_outputFolderName->setVisible(true);
        ui->label_outputFolderName->setVisible(true);
        ui->lineEdit_MARCount->setVisible(true);
        ui->label_MARCount->setVisible(true);

        // 恢复label_outputFolderName字体颜色为黑色
        QPalette palette = ui->label_outputFolderName->palette();
        palette.setColor(QPalette::WindowText, Qt::black);
        ui->label_outputFolderName->setPalette(palette);
        ui->label_MARCount->setPalette(palette);
    }
    else if (index == 1)
    {
        // 设置按钮和输入框不可见
        ui->pushButton_readconvert->setText("读取txt文件");
        ui->lineEdit_outputFolderName->setVisible(false);
        ui->label_outputFolderName->setVisible(false);
        ui->lineEdit_MARCount->setVisible(false);
        ui->label_MARCount->setVisible(false);
    }
}


void MainWindow::convertPtuToTxt(const QString &sourceFilePath, const QString &outputFilePath)
{
    QProcess *ptuProcess = new QProcess(this);
    // 获取应用程序的目录路径
    QString appDir = QCoreApplication::applicationDirPath();

    // 构建 ptudemo.exe 的绝对路径
    QString ptuDemoPath = appDir + "/exeProcess/ptudemo.exe";

    // 调用外部程序 ptudemo.exe 转换 .ptu 文件为 .txt 文件
    ptuProcess->start(ptuDemoPath, QStringList() << sourceFilePath << outputFilePath);
    qDebug() << "ptudemo.exe的路径" << ptuDemoPath;
    qDebug() << "soruceFilePath的路径" << sourceFilePath;
    qDebug() << "outputFilePath的路径" << outputFilePath;

    // 等待外部程序启动
    if (!ptuProcess->waitForStarted()) {
        qWarning() << "Failed to start" << ptuDemoPath;
        return;
    }

    // 等待外部程序完成
    if (!ptuProcess->waitForFinished(-1)) {
        // 获取外部程序的输出和错误信息
        QByteArray stdoutData = ptuProcess->readAllStandardOutput();
        QByteArray stderrData = ptuProcess->readAllStandardError();

        // 打印详细的错误信息
        qWarning() << "Failed to convert" << sourceFilePath << "to" << outputFilePath;
        qWarning() << "Standard Output:" << stdoutData;
        qWarning() << "Standard Error:" << stderrData;
    } else {
        qInfo() << "Successfully converted" << sourceFilePath << "to" << outputFilePath;
    }
}

void MainWindow::readAndConvertFiles(int index)
{
    // 获取用户的主目录作为默认路径
    QString dir = QCoreApplication::applicationDirPath();
    const char *dialogTitle = index == 0 ? "请选择ptu文件所在的文件夹" : "请选择txt文件所在的文件夹";
    // 打开文件夹选择对话框
    QString folderPath = QFileDialog::getExistingDirectory(
                this,                    // 父窗口
                tr(dialogTitle),        // 对话框标题
                dir,                     // 默认路径
                QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks // 选项
            );

    // 如果用户选择了文件夹，则查找文件
    if (!folderPath.isEmpty()) {
        QDir directory(folderPath);
        QFileInfoList files;

        if (index == 0) {
            // 查找 .ptu 文件
            files = directory.entryInfoList(QStringList() << "*.ptu", QDir::Files);
        } else if (index == 1) {
            // 查找 .txt 文件
            files = directory.entryInfoList(QStringList() << "*.txt", QDir::Files);
            // 删除 all_valid_files.txt 文件
            QString fileToDelete = directory.absoluteFilePath("all_valid_files.txt");
            if (QFile::exists(fileToDelete)) {
                if (QFile::remove(fileToDelete)) {
                    qDebug() << "File" << fileToDelete << "deleted successfully.";
                } else {
                    qDebug() << "Failed to delete file" << fileToDelete;
                }
            } else {
                qDebug() << "File" << fileToDelete << "does not exist.";
            }
        }

        // 清空 tableWidget
        ui->tableWidget_filesInfo->clearContents();
        ui->tableWidget_filesInfo->setRowCount(0);

        // 使用 QMap 来存储每个前缀对应的文件列表
        QMap<QString, QStringList> fileMap;

        // 创建一个用于排序的前缀列表
        QVector<QString> prefixes;

        for (const QFileInfo &fileInfo : files) {
            QString fileName = fileInfo.fileName();
            // 使用 "_" 分割文件名，取第一个部分作为前缀
            QString prefix = fileName.section('_', 0, 0);
            fileMap[prefix].append(fileName);
            // 添加前缀到列表中
            if (!prefixes.contains(prefix) && prefix != "all") {
                prefixes.append(prefix);
            }
        }

        // 使用自定义比较函数对前缀列表进行排序
        std::sort(prefixes.begin(), prefixes.end(), comparePrefixes);

        // 计算所需的行数
        int rowCount = prefixes.size();
        // 计算每行的最大文件数量
        int maxFileCount = 0;
        for (const QString &prefix : prefixes) {
            int fileCount = fileMap[prefix].size();
            if (fileCount > maxFileCount) {
                maxFileCount = fileCount;
            }
        }

        int colCount = maxFileCount; // 每行的最大文件数量

        // 设置 tableWidget 的行数和列数
        ui->tableWidget_filesInfo->setRowCount(rowCount);
        ui->tableWidget_filesInfo->setColumnCount(colCount);

        QString outputFolderPath;
        if (index == 0)
        {
            QString outputFileName = ui->lineEdit_outputFolderName->text();
            // 创建输出文件夹
            outputFolderPath = directory.path() + "/../" + outputFileName;
            QDir().mkpath(outputFolderPath); // 确保输出文件夹存在
        }
        else
        {
            outputFolderPath = directory.path();
        }

        // 设置进度条相关属性
        int totalFiles = files.size();
        int currentFile = 0;
        ui->progressBar->setValue(0);
        ui->progressBar->setFormat("正在读取文件中，当前进度：%p%");
        ui->progressBar->setTextVisible(true);

        // 清空现有的文件名和路径映射
        fileNameToAbsolutePath.clear();

        // 遍历所有文件，处理文件
        for (const QString &prefix : prefixes) {
            const QStringList &files = fileMap[prefix];
            for (int col = 0; col < colCount && col < files.size(); ++col) {
                QString fileName = files[col];
                QString sourceFilePath = directory.absoluteFilePath(fileName);
                QString outputFileName = fileName.split('.')[0] + ".txt";
                QString outputFilePath = outputFolderPath + "/" + outputFileName;

                // 转换文件或直接显示
                if (index == 0) {
                    convertPtuToTxt(sourceFilePath, outputFilePath);
                    outputFileName = outputFilePath.split('/').last();
                }

                // 显示文件名
                QTableWidgetItem *item = new QTableWidgetItem(outputFileName);
                if (outputFileName != "all_valid_files.txt")
                {
                    ui->tableWidget_filesInfo->setItem(prefixes.indexOf(prefix), col, item);
                }

                // 存储文件名和绝对路径
                fileNameToAbsolutePath[outputFileName] = outputFilePath;

                // 更新进度条
                currentFile++;
                int progress = (currentFile * 100) / totalFiles;
                ui->progressBar->setValue(progress);
                qApp->processEvents(); // 确保界面更新
            }

            // 设置垂直头标签
            ui->tableWidget_filesInfo->setVerticalHeaderItem(prefixes.indexOf(prefix), new QTableWidgetItem(prefix));
        }

        // 调用 is_valid_file.exe 判断文件是否有效
        if (index == 0 || index == 1) {
            QProcess process;
            QStringList arguments;

            arguments << outputFolderPath << "400,96"; // 传递文件夹路径和目标计数

            // 连接错误信号
            connect(&process, &QProcess::errorOccurred, [&](QProcess::ProcessError error) {
                qDebug() << "Process error:" << error;
            });

            qDebug() << "Starting process with arguments:" << arguments;
            qDebug() << "Output folder path:" << outputFolderPath;
            process.start("exeProcess/is_valid_file.exe", arguments);

            if (!process.waitForStarted()) {
                qDebug() << "Failed to start process";
                return;
            }

            if (!process.waitForFinished()) {
                qDebug() << "Process did not finish within the timeout period";
                return;
            }

            int exitCode = process.exitCode();
            qDebug() << "Process exit code:" << exitCode;

            // 读取 all_valid_files.txt 文件
            QString allValidFilePath = outputFolderPath + "/all_valid_files.txt";
            if (QFile::exists(allValidFilePath)) {
                QFile allValidFile(allValidFilePath);
                if (allValidFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
                    QTextStream in(&allValidFile);
                    QHash<QString, bool> validFiles;

                    while (!in.atEnd()) {
                        QString line = in.readLine();
                        QStringList parts = line.split(": ");
                        if (parts.size() == 2) {
                            QString fileNameInResult = parts[0];
                            QString result = parts[1];
                            bool isValid = result.startsWith("400 MAR records found") || result.startsWith("96 MAR records found");
                            validFiles[fileNameInResult] = isValid;
                        }
                    }
                    allValidFile.close();

                    // 更新 tableWidget 中的项
                    for (int row = 0; row < rowCount; ++row) {
                        for (int col = 0; col < colCount; ++col) {
                            QTableWidgetItem *item = ui->tableWidget_filesInfo->item(row, col);
                            if (item) {
                                QString fileName = item->text();
                                bool isValid = validFiles.value(fileName, false); // 默认值为 false，表示无效文件
                                if (!isValid) {
                                    item->setBackground(Qt::red); // 设置背景色为红色
                                    item->setFlags(item->flags() & ~Qt::ItemIsSelectable); // 设置为不可选
                                    item->setFlags(item->flags() & ~Qt::ItemIsEditable); // 确保不可编辑
                                }
                                else
                                {
                                    item->setFlags(item->flags() & ~Qt::ItemIsEditable); // 确保不可编辑
                                }
                            }
                        }
                    }
                } else {
                    qDebug() << "Failed to open all_valid_files.txt";
                }
            } else {
                qDebug() << "all_valid_files.txt does not exist";
            }
            ui->progressBar->setValue(100);
            ui->progressBar->setFormat("已成功读取文件");
        }
    }
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Delete) {
        // 获取 listWidget 中选中的项
        QList<QListWidgetItem *> selectedItems = ui->listWidget_filesInfo->selectedItems();

        // 如果有选中的项，则删除它们
        if (!selectedItems.isEmpty()) {
            foreach (QListWidgetItem *item, selectedItems) {
                QString fileName = item->text();
                bool ok;
                int prefixNum = fileName.section('.', 0, 0).mid(1).section('_', 0, 0).toInt(&ok);
                if (ok) {
                    addedFiles.remove(prefixNum);
                }
                delete item;
            }
        } else {
            // 如果没有选中的项，提示用户
            QMessageBox::information(this, tr("提示"), tr("请先选择要删除的项。"));
        }
    } else if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
        QList<QTableWidgetItem*> selectedItems = ui->tableWidget_filesInfo->selectedItems();
        if (!selectedItems.isEmpty()) {
            addSelectedItemToListWidget(selectedItems.first());
        }
    } else {
        QWidget::keyPressEvent(event);
    }
}

void MainWindow::addSelectedItemToListWidget(QTableWidgetItem *item)
{
    if (item) {
        QString fileName = item->text();
        QString prefix = fileName.section('.', 0, 0);

        // 提取前缀中的数字部分
        bool ok;
        int prefixNum = prefix.mid(1).section('_', 0, 0).toInt(&ok);
        if (!ok) return; // 如果转换失败，返回

        // 检查是否已经添加过该前缀的文件
        if (!addedFiles.contains(prefixNum)) {
            addedFiles[prefixNum] = fileName;

            // 重新填充 listWidget，确保前缀按正确顺序排列
            ui->listWidget_filesInfo->clear();
            for (auto it = addedFiles.begin(); it != addedFiles.end(); ++it) {
                ui->listWidget_filesInfo->addItem(it.value());
            }
        }
    }
}

// 判断lineEdit_MARCount的输入内容是否有效
bool isInputValid(const QString &input)
{
    // 定义正则表达式，匹配一个或多个数字，且数字之间用逗号分隔
    QRegularExpression regex(R"(^\d+(,\d+)*$)");
    QRegularExpressionMatch match = regex.match(input);

    // 如果匹配成功，返回 true，否则返回 false
    return match.hasMatch();
}

void MainWindow::on_pushButton_readconvert_clicked()
{
    int comboBox_index = ui->comboBox->currentIndex();

    if (comboBox_index == 0)
    {     
        bool isEmpty_lineEdit_outputFolderName = ui->lineEdit_outputFolderName->text().isEmpty();
        bool isEmpty_lineEdit_MARCount = ui->lineEdit_MARCount->text().isEmpty();
        // 判断lineEdit_MARCount的输入内容是否有效
        QString lineEdit_MARCount_input = ui->lineEdit_MARCount->text();
        bool isValidNumber = isInputValid(lineEdit_MARCount_input);
        if (isValidNumber == false)
        {
            QMessageBox::warning(this, tr("警告"), tr("请检查图片数量输入是否正确(有多个数字时以英文逗号分隔W)"));
            return;
        }

        if (!isEmpty_lineEdit_outputFolderName && isValidNumber && !isEmpty_lineEdit_MARCount)
            readAndConvertFiles(0);
        else if (isEmpty_lineEdit_MARCount && isEmpty_lineEdit_outputFolderName)
        {
            // 设置字体为红色
            QPalette palette = ui->label_MARCount->palette();
            palette.setColor(QPalette::WindowText, Qt::red);
            ui->label_MARCount->setPalette(palette);
            ui->label_outputFolderName->setPalette(palette);
            QMessageBox::warning(this, tr("警告"), tr("请输入输出文件夹名称和每个文件所含图片数量"));
        }
        else if (isEmpty_lineEdit_MARCount)
        {
            // 设置字体为红色
            QPalette palette = ui->label_MARCount->palette();
            palette.setColor(QPalette::WindowText, Qt::red);
            ui->label_MARCount->setPalette(palette);
            QMessageBox::warning(this, tr("警告"), tr("每个文件所含图片数量"));
        }
        else if (isEmpty_lineEdit_outputFolderName)
        {
            QPalette palette = ui->label_outputFolderName->palette();
            palette.setColor(QPalette::WindowText, Qt::red);
            ui->label_outputFolderName->setPalette(palette);
            QMessageBox::warning(this, tr("警告"), tr("请输入输出文件夹名称"));
        }
    }
    else if (comboBox_index == 1)
    {
        readAndConvertFiles(1);
    }
}

void MainWindow::on_tableWidget_filesInfo_cellDoubleClicked(int row, int column)
{
    QTableWidgetItem *item = ui->tableWidget_filesInfo->item(row, column);
    if (item) {
        addSelectedItemToListWidget(item);
    }
}


void MainWindow::on_pushButton_randomSelectFiles_clicked()
{
    // 清空 listWidget_filesInfo
    ui->listWidget_filesInfo->clear();

    // 获取 tableWidget 的行数和列数
    int rowCount = ui->tableWidget_filesInfo->rowCount();
    int colCount = ui->tableWidget_filesInfo->columnCount();

    // 使用 QMap 来存储每个前缀对应的文件列表
    QMap<QString, QList<QTableWidgetItem*>> validFiles;

    // 记录没有有效文件的前缀
    QStringList invalidPrefixes;

    // 遍历 tableWidget，收集有效的文件
    for (int row = 0; row < rowCount; ++row) {
        bool hasValidFile = false;
        for (int col = 0; col < colCount; ++col) {
            QTableWidgetItem *item = ui->tableWidget_filesInfo->item(row, col);
            if (item && item->background().color() != Qt::red) {
                hasValidFile = true;
                QString prefix = ui->tableWidget_filesInfo->verticalHeaderItem(row)->text();
                validFiles[prefix].append(item);
            }
        }
        if (!hasValidFile) {
            QString prefix = ui->tableWidget_filesInfo->verticalHeaderItem(row)->text();
            invalidPrefixes.append(prefix);
        }
    }

    // 检查是否有无效的前缀
    if (!invalidPrefixes.isEmpty()) {
        QString message = tr("以下前缀没有有效的文件：\n");
        for (const QString &prefix : invalidPrefixes) {
            message += prefix + "\n";
        }
        QMessageBox::warning(this, tr("文件选择错误"), message);
    }
    // 将前缀列表提取到一个 QVector 中
    QVector<QString> prefixes;
    for (const QString &key : validFiles.keys()) {
        prefixes.append(key);
    }

    // 使用自定义比较函数对前缀进行排序
    std::sort(prefixes.begin(), prefixes.end(), comparePrefixes);

    // 随机选择每个前缀的一个文件
    for (const QString &prefix : prefixes) {
        const QList<QTableWidgetItem*> &items = validFiles[prefix];
        if (!items.isEmpty()) {
            // 随机选择一个文件
            int randomIndex = qrand() % items.size();
            QTableWidgetItem *selectedItem = items[randomIndex];

            // 将选中的文件添加到 listWidget_filesInfo
            ui->listWidget_filesInfo->addItem(selectedItem->text());
        }
    }

}

void MainWindow::on_pushButton_selectPtFile_clicked()
{
    // 打开文件选择对话框，设置过滤器为 .pt 文件
    QString filePath = QFileDialog::getOpenFileName(this, tr("选择 .pt 文件"), "", tr("PyTorch 模型文件 (*.pt);;所有文件 (*)"));

    // 检查用户是否选择了文件
    if (!filePath.isEmpty()) {
        // 检查文件扩展名是否为 .pt
        if (filePath.endsWith(".pt", Qt::CaseInsensitive)) {
            ptFilePath = filePath;
            QFileInfo fileInfo(filePath);
            QString fileName = fileInfo.fileName();

            // 在 QLabel 中显示文件名
            ui->label_ptFileName->setText(fileName); // 假设你有一个 QLabel 来显示文件名

        } else {
            // 显示错误消息
            QMessageBox::warning(this, tr("文件选择错误"), tr("请选择一个 .pt 结尾的文件。"));
        }
    }
}

void MainWindow::on_pushButton_reconstructImage_2_clicked()
{
    if (ui->comboBox_reconstructImage->currentIndex() == 2)
    {
        // 获取 tableWidget 的行数（假设你是要比较行数而不是列数）
        int rowCount = ui->tableWidget_filesInfo->rowCount();

        // 获取 listWidget 的选中项数量
        QList<QListWidgetItem*> selectedItems = ui->listWidget_filesInfo->selectedItems();
        int selectedItemCount = ui->listWidget_filesInfo->count();

        // 检查选中项数量是否与行数一致
        if (selectedItemCount != rowCount) {
            qDebug() << "rowCount = " << rowCount;
            qDebug() << "selectedItemCount = " << selectedItemCount;
            QMessageBox::warning(this, tr("警告"), tr("选择的项数量必须与表格中的行数一致。"));
            return;
        }

        // 获取 lineEdit 的值
        QString pictureName = ui->lineEdit_imageName->text().trimmed();
        if (pictureName.isEmpty()) {
            QMessageBox::warning(this, tr("警告"), tr("请输入图片名称"));
            return;
        }

        // 构建文件列表
        QStringList fileList;
        for (int i = 0; i < selectedItemCount; ++i) {
            QListWidgetItem *item = ui->listWidget_filesInfo->item(i);
            if (item) {
                QString fileName = item->text();
                // 在 fileNameToAbsolutePath 中查找对应的绝对路径
                if (fileNameToAbsolutePath.contains(fileName)) {
                    QString absolutePath = fileNameToAbsolutePath[fileName];
                    fileList << absolutePath;
                } else {
                    // 如果文件名不在映射中，可以处理错误或跳过
                    qWarning() << "File not found in the map:" << fileName;
                }
            }
        }

        // 打印调试信息
        qDebug() << "Selected items count:" << selectedItemCount;
        qDebug() << "File list before calling Python script:" << fileList;

        // 检查文件列表是否为空
        if (fileList.isEmpty()) {
            QMessageBox::warning(this, tr("警告"), tr("文件列表为空，请选择有效的文件。"));
            return;
        }

        // 计算输出图像保存路径（txt 文件路径的上一级目录下的 output_image 文件夹）
        QFileInfo fileInfo(fileList.first()); // 假设所有文件在同一目录下，取第一个文件路径作为参考
        QDir outputDir(fileInfo.absolutePath());
        outputDir.cdUp(); // 上一级目录
        outputDir.mkpath("output_image"); // 创建或确保存在 output_image 文件夹
        QString outputPath = outputDir.absoluteFilePath("output_image");

        // 构建命令行参数
        QStringList arguments;
        arguments << fileList;
        arguments << "--output-path" << outputPath;
        arguments << "--output-name" << pictureName;

        QString appDir = QCoreApplication::applicationDirPath();
        QString exePath = appDir + "/exeProcess/interval_photo_num.exe";
        QProcess process;
        qDebug() << "exePath" << exePath;
        qDebug() << "arguments" << arguments;
        process.start(exePath, arguments);
        if (!process.waitForStarted()) {
            QMessageBox::critical(this, tr("错误"), tr("无法启动外部程序。"));
            return;
        }

        if (!process.waitForFinished(-1)) { // -1 表示无限期等待直到进程结束
            QMessageBox::critical(this, tr("错误"), tr("外部程序执行失败。"));
            return;
        }

        // 检查是否有错误输出
        if (process.exitCode() != 0) {
            QByteArray errorOutput = process.readAllStandardError();
            qDebug() << "External program error:" << errorOutput;
            QMessageBox::critical(this, tr("错误"), tr("外部程序运行时发生错误。"));
            return;
        }

        qDebug() << "External program executed successfully.";
        QString picutrePath = outputPath + "//" + pictureName;
        setUpPicture(picutrePath, ui->label_Image3);
        return;
    }
    // 光子计数恢复图像
    else if (ui->comboBox_reconstructImage->currentIndex() == 1)
    {
        // 获取 tableWidget 的行数（假设你是要比较行数而不是列数）
        int rowCount = ui->tableWidget_filesInfo->rowCount();

        // 获取 listWidget 的选中项数量
        QList<QListWidgetItem*> selectedItems = ui->listWidget_filesInfo->selectedItems();
        int selectedItemCount = ui->listWidget_filesInfo->count();

        // 检查选中项数量是否与行数一致
        if (selectedItemCount != rowCount) {
            qDebug() << "rowCount = " << rowCount;
            qDebug() << "selectedItemCount = " << selectedItemCount;
            QMessageBox::warning(this, tr("警告"), tr("选择的项数量必须与表格中的行数一致。"));
            return;
        }

        // 获取 lineEdit 的值
        QString pictureName = ui->lineEdit_imageName->text().trimmed();
        if (pictureName.isEmpty()) {
            QMessageBox::warning(this, tr("警告"), tr("请输入图片名称"));
            return;
        }

        // 构建文件列表
        QStringList fileList;
        for (int i = 0; i < selectedItemCount; ++i) {
            QListWidgetItem *item = ui->listWidget_filesInfo->item(i);
            if (item) {
                QString fileName = item->text();
                // 在 fileNameToAbsolutePath 中查找对应的绝对路径
                if (fileNameToAbsolutePath.contains(fileName)) {
                    QString absolutePath = fileNameToAbsolutePath[fileName];
                    fileList << absolutePath;
                } else {
                    // 如果文件名不在映射中，可以处理错误或跳过
                    qWarning() << "File not found in the map:" << fileName;
                }
            }
        }

        // 打印调试信息
        qDebug() << "Selected items count:" << selectedItemCount;
        qDebug() << "File list before calling Python script:" << fileList;

        // 检查文件列表是否为空
        if (fileList.isEmpty()) {
            QMessageBox::warning(this, tr("警告"), tr("文件列表为空，请选择有效的文件。"));
            return;
        }

        // 计算输出图像保存路径（txt 文件路径的上一级目录下的 output_image 文件夹）
        QFileInfo fileInfo(fileList.first()); // 假设所有文件在同一目录下，取第一个文件路径作为参考
        QDir outputDir(fileInfo.absolutePath());
        outputDir.cdUp(); // 上一级目录
        outputDir.mkpath("output_image"); // 创建或确保存在 output_image 文件夹
        QString outputPath = outputDir.absoluteFilePath("output_image");

        // 构建命令行参数
        QStringList arguments;
        arguments << fileList;
        arguments << "--output-path" << outputPath;
        arguments << "--output-name" << pictureName;
        arguments << "--pt-file-path" << ptFilePath;

        QString appDir = QCoreApplication::applicationDirPath();
        QString exePath = appDir + "/exeProcess/phtot_num_reconstruct.exe";
        QProcess process;
        qDebug() << "exePath" << exePath;
        qDebug() << "arguments" << arguments;
        process.start(exePath, arguments);
        if (!process.waitForStarted()) {
            QMessageBox::critical(this, tr("错误"), tr("无法启动外部程序。"));
            return;
        }

        if (!process.waitForFinished(-1)) { // -1 表示无限期等待直到进程结束
            QMessageBox::critical(this, tr("错误"), tr("外部程序执行失败。"));
            return;
        }

        // 检查是否有错误输出
        if (process.exitCode() != 0) {
            QByteArray errorOutput = process.readAllStandardError();
            qDebug() << "External program error:" << errorOutput;
            QMessageBox::critical(this, tr("错误"), tr("外部程序运行时发生错误。"));
            return;
        }

        qDebug() << "External program executed successfully.";
        QString picutrePath = outputPath + "//" + pictureName;
        setUpPicture(picutrePath, ui->label_Image2);
        return;
    }


    if (ui->lineEdit_photoNum->text().isEmpty() && ui->lineEdit_imageName->text().isEmpty())
    {
        QPalette palette = ui->label_imageName->palette();
        palette.setColor(QPalette::WindowText, Qt::red);
        ui->label_imageName->setPalette(palette);
        ui->label_photoNum->setPalette(palette);
        QMessageBox::warning(this, tr("警告"), tr("请输入图片名称和光子数"));
        return;
    }
    else if (ui->lineEdit_photoNum->text().isEmpty())
    {
        QPalette palette = ui->label_photoNum->palette();
        palette.setColor(QPalette::WindowText, Qt::red);
        ui->label_photoNum->setPalette(palette);
        QMessageBox::warning(this, tr("警告"), tr("请输入光子数"));
        return;
    }
    else if (ui->lineEdit_imageName->text().isEmpty())
    {
        QPalette palette = ui->label_imageName->palette();
        palette.setColor(QPalette::WindowText, Qt::red);
        ui->label_imageName->setPalette(palette);
        QMessageBox::warning(this, tr("警告"), tr("请输入图片名称"));
        return;
    }

    // 获取 tableWidget 的行数（假设你是要比较行数而不是列数）
    int rowCount = ui->tableWidget_filesInfo->rowCount();

    // 获取 listWidget 的选中项数量
    QList<QListWidgetItem*> selectedItems = ui->listWidget_filesInfo->selectedItems();
    int selectedItemCount = ui->listWidget_filesInfo->count();

    // 检查选中项数量是否与行数一致
    if (selectedItemCount != rowCount) {
        qDebug() << "rowCount = " << rowCount;
        qDebug() << "selectedItemCount = " << selectedItemCount;
        QMessageBox::warning(this, tr("警告"), tr("选择的项数量必须与表格中的行数一致。"));
        return;
    }

    // 获取 lineEdit 的值
    int pulseCount = ui->lineEdit_photoNum->text().toInt();
    QString pictureName = ui->lineEdit_imageName->text();

    // 构建文件列表
    QStringList fileList;
    for (int i = 0; i < selectedItemCount; ++i) {
        QListWidgetItem *item = ui->listWidget_filesInfo->item(i);
        if (item) {
            QString fileName = item->text();
            // 在 fileNameToAbsolutePath 中查找对应的绝对路径
            if (fileNameToAbsolutePath.contains(fileName)) {
                QString absolutePath = fileNameToAbsolutePath[fileName];
                fileList << absolutePath;
            } else {
                // 如果文件名不在映射中，可以处理错误或跳过
                qWarning() << "File not found in the map:" << fileName;
            }
        }
    }

    // 打印调试信息
    qDebug() << "Selected items count:" << selectedItemCount;
    qDebug() << "File list before calling Python script:" << fileList;

    // 检查文件列表是否为空
    if (fileList.isEmpty()) {
        QMessageBox::warning(this, tr("警告"), tr("文件列表为空，请选择有效的文件。"));
        return;
    }

    // 将文件路径转换为 JSON 格式
    QJsonArray jsonArray;
    for (const QString &file : fileList) {
        jsonArray.append(file);
    }
    QJsonDocument jsonDoc(jsonArray);
    QString fileListJson = jsonDoc.toJson(QJsonDocument::Compact);

    // 调用 Python 可执行文件
    QString realPictName = callPythonExecutable(fileListJson, pulseCount, pictureName);
    setUpPicture(realPictName, ui->label_Image1);
}

QString MainWindow::callPythonExecutable(const QString &fileListJson, int pulseCount, const QString &pictureName)
{
    // 构建参数
    QString userOutputDir = ui->lineEdit_outputImageFolderName->text();
    QStringList args;

    QString outputDir;
    if (userOutputDir.isEmpty()) {
        QJsonDocument doc = QJsonDocument::fromJson(fileListJson.toUtf8());
        QJsonArray jsonArray = doc.array();
        if (!jsonArray.isEmpty()) {
            QString firstFilePath = jsonArray[0].toString();
            QFileInfo fileInfo(firstFilePath);
            QString fileDir = fileInfo.absolutePath() + "/..";
            outputDir = fileDir + "/output_image";
            QDir().mkpath(outputDir);
        } else {
            qWarning() << "File list is empty, cannot determine the output directory.";
            return "";
        }
    } else {
        outputDir = userOutputDir;
        QDir().mkpath(outputDir);
    }

    qDebug() << "outputDir" << outputDir;
    args << fileListJson << QString::number(pulseCount) << outputDir << pictureName;
    if (!ptFilePath.isEmpty()) {
        args << ptFilePath;
    } else {
        qWarning() << "No .pt file selected, please select a .pt file before calling the executable.";
        return "";
    }
    qDebug() << "args" << args;
        // 构建可执行文件的完整路径
    QString appDir = QCoreApplication::applicationDirPath();
    QString pythonExePath = appDir + "/exeProcess/difference_calculating1.exe";
    QProcess process;

    // 连接标准输出和标准错误信号
    connect(&process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
            this, [this, &process](int exitCode, QProcess::ExitStatus exitStatus) {
        if (exitStatus == QProcess::NormalExit) {
            qInfo() << "Python script finished successfully with exit code:" << exitCode;
        } else {
            qWarning() << "Python script crashed with exit code:" << exitCode;
        }
    });

    connect(&process, &QProcess::readyReadStandardOutput, this, [&process]() {
        QByteArray stdoutData = process.readAllStandardOutput();
        qDebug() << "Standard Output:" << QString::fromLocal8Bit(stdoutData);
    });

    connect(&process, &QProcess::readyReadStandardError, this, [&process]() {
        QByteArray stderrData = process.readAllStandardError();
        qWarning() << "Standard Error:" << QString::fromLocal8Bit(stderrData);
    });

    process.start(pythonExePath, args);

    if (!process.waitForStarted()) {
        qWarning() << "Failed to start" << pythonExePath;
        return "";
    }

    if (!process.waitForFinished(-1)) {
        qWarning() << "Failed to finish" << pythonExePath;
        return "";
    }

    // 获取外部程序的输出和错误信息
    QByteArray stdoutData = process.readAllStandardOutput();
    QByteArray stderrData = process.readAllStandardError();

    // 打印详细的输出和错误信息
    qInfo() << "Standard Output:" << QString::fromLocal8Bit(stdoutData);
    qWarning() << "Standard Error:" << QString::fromLocal8Bit(stderrData);

    // 获取进程的退出码
    int exitCode = process.exitCode();
    QProcess::ExitStatus exitStatus = process.exitStatus();

    if (exitStatus == QProcess::NormalExit && exitCode == 0) {
        qInfo() << "Python script finished successfully.";
    } else {
        qWarning() << "Python script failed with exit code:" << exitCode;
    }

    return outputDir + "/" + ui->lineEdit_imageName->text();
}

void MainWindow::setUpPicture(QString pictureName, QLabel *label)
{
    QString imageDir = pictureName + ".png";
    // 检查图像文件是否存在
    if (!QFile::exists(imageDir)) {
        QMessageBox::warning(this, tr("警告"), tr("图像文件不存在。"));
        return;
    }

    // 加载图像
    QPixmap pixmap(imageDir);

    // 检查图像是否加载成功
    if (pixmap.isNull()) {
        QMessageBox::warning(this, tr("警告"), tr("无法加载图像。"));
        return;
    }

    // 将图像设置到 QLabel 中
    label->setPixmap(pixmap.scaled(ui->label_Image1->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
}

void MainWindow::on_comboBox_reconstructImage_currentIndexChanged(int index)
{
    if (index == 0)
    {
        ui->pushButton_reconstructImage_2->setText("脉冲差值恢复图像");
        ui->lineEdit_photoNum->setVisible(true);
        ui->label_photoNum->setVisible(true);
    }
    else if (index == 1)
    {
        ui->pushButton_reconstructImage_2->setText("光子计数恢复图像");
        ui->lineEdit_photoNum->setVisible(false);
        ui->label_photoNum->setVisible(false);
    }
    else if (index == 2)
    {
        ui->pushButton_reconstructImage_2->setText("生成MAR之间光子数折线图");
        ui->lineEdit_photoNum->setVisible(false);
        ui->label_photoNum->setVisible(false);
    }
}
